<?php

class Sgit_Controller_Action_Edit extends Zend_Controller_Action
{

    protected $_main_model;
    protected $_main_form;
    protected $_checkZona = false;
    protected $_checkAcceso = true;
    protected $_checkSession = true;
    protected $_id_tablesorter = 'myTable';
    protected $_cache = null;
    protected $_idZona = null;
    protected $_auth = null;
    protected $_sgit_session = null;
    protected $_profiler = true;


    /**
     * Sgit_Controller_Action::init()
     * 
     * @return
     */
    public function init()
    {

       


        if ($this->_profiler)
        {
            $db = Zend_Registry::get("database");
            $db->getProfiler()->setEnabled(true);
        }



        //aqui guardamos todas los modelos instanciados
        $this->_model = new stdClass();
        //aqui guardamos todas los formularios instanciados
        $this->_form = new stdClass();
        //aqui guardamos form elements
        $this->_element = new stdClass();

        //guradomos el request aqui
        $this->request = $this->getRequest();

        //guardamos modelos precargados
        if ($this->_main_model)
        {
            $model = 'Application_Model_' . $this->_main_model;
            $this->_model->default = new $model();
        }


        //creo una serie de variables utiles tanbto en el action como en la vista
        $this->_actionName = $this->request->getActionName();
        $this->_controllerName = $this->request->getControllerName();
        $this->view->id_tablesorter = $this->_id_tablesorter;
        $this->view->actionName = $this->_actionName;
        $this->view->controllerName = $this->_controllerName;


        //comprueba si esta autenticado
        $this->_auth();

        //comprueba si se necesita zona y setea las variable de zonas
        $this->_zona();

        //comprueba que tiene permiso para realizar esta accion
        $this->_acl();

        //carga zend navigation y usa los herlper breadcrubms y pone el title
        $this->_navigation();

        $this->_begin();


    }
    

    /**
     * Esta funcion es para reemplazar el init Zend_Controller_Action
     * 
     */
    protected function _begin()
    {
    }


    /**
     * acceso rapido para obtener los datacenters
     * devuelve las zoans y crea la variable de vista zonas 
     */
    protected function _getNombreZona($id)
    {
        $this->_loadModel('Datacenter');
        return $this->_model->Datacenter->getNombreZona($id);
    }


    /**
     * 
     * acceso rapido para obtener los datacenters
     * devuelve las zoans y crea la variable de vista zonas 
     */

    /**
     * Sgit_Controller_Action::_getZonas()
     * 
     * @return
     */
    protected function _getZonas()
    {
        $this->_loadModel('Datacenter');
        $this->view->zonas = $this->_model->Datacenter->getAssoc('id', 'nombre', array('dc=?' => 1));
        return $this->view->zonas;
    }

    protected function _navigation()
    {
        if ($this->_checkSession)
        {
            if ($this->_auth->hasIdentity())
            {
                $uri = $this->_request->getPathInfo();
                $navigation = $this->view->navigation();
                $navigation->setAcl($this->_acl);
                $navigation->setRole((string )$this->_auth->getIdentity()->id);


                $breadToTitle = $navigation->breadcrumbs()->render();

                foreach ((array )explode('&gt;', strip_tags($breadToTitle)) as $v)
                {
                    $this->view->headTitle($v);
                }
            }
        }

    }


    public function indexAction()
    {
        $this->view->headTitle('Page not developed');
        $this->_helper->viewRenderer->setNoRender(true);

        echo '<h1>Error</h1>
        <h2>Page not developed</h2>
        <p>You are trying to access an area not developed.</p>';

    }


    final public function deniedAction()
    {
    }


    final public function registerAction()
    {


        $this->_helper->viewRenderer->setNoRender(true);
        $this->_helper->layout->disableLayout();
        $this->_updateAcl();
        $this->_acl = $this->_getAcl();

        if ($this->_checkZona)
        {
            $zonas = $this->_getZonas();

            foreach ($zonas as $k => $idZona)
            {
                $this->_register($k);
            }
        } else
        {
            $this->_register();
        }


        $this->_acl = $this->_setAcl($this->_acl);

        $param = array('idZona' => $this->_idZona);

        if ($this->_checkZona)
            $this->_helper->redirector->gotoSimple('index', $this->_controllerName, null, $param);
        else
            $this->_helper->redirector->gotoSimple('index', $this->_controllerName);


    }


    protected function _register($idZona = null)
    {

        $this->_loadModel('Datacenter');
        $this->_loadModel('AclResources');


        $codZona = is_numeric($idZona) ? ':' . $idZona : '';

        $key_parent = strtolower($this->_controllerName . $codZona);

        $zona = $this->_model->Datacenter->getNombreZona($idZona);

        $row_padre = $this->_model->AclResources->getRow(array('resource = ?' => $key_parent));

        if (!$row_padre)
        {
            $this->_model->AclResources->insert(array('resource' => $key_parent, 'notas' => 'Todas las acciones de ' . $this->_controllerName . ' ' . $zona));
        }

        //sino hay recurso padre se crea
        if (!$this->_acl->has($key_parent))
        {
            $this->_acl->add(new Zend_Acl_Resource($key_parent));
        }

        foreach (get_class_methods($this) as $v)
        {
            if (in_array($v, array('deniedAction', 'registerAction')))
                continue;

            if (strpos($v, 'Action'))
            {
                $action = str_replace('Action', '', $v);

                $check_auth = 1;
                $notas = null;

                switch ($action)
                {
                    case 'index':
                        $notas = 'Página principal de ' . $this->_controllerName . ' ' . $zona;
                        break;
                    case 'editar':
                        $notas = 'Editar ' . $this->_controllerName . ' ' . $zona;
                        break;
                    case 'insertar':
                        $notas = 'Insertar ' . $this->_controllerName . ' ' . $zona;
                        break;
                    case 'borrar':
                        $notas = 'Borrar ' . $this->_controllerName . ' ' . $zona;
                        break;
                    case 'autocomplete':
                        $check_auth = 0;
                        break;
                }


                $key_resource = strtolower($this->_controllerName . ':' . $action . $codZona);
                $row = $this->_model->AclResources->getRow(array('resource = ?' => $key_resource));


                if (!$row)
                {
                    $this->_model->AclResources->insert(array('resource' => $key_resource, 'parent' => $key_parent, 'notas' => $notas, 'check_auth' => $check_auth));
                }


                if (!$this->_acl->has($key_resource))
                {
                    $this->_acl->add(new Zend_Acl_Resource($key_resource));
                }
            }
        }
        return true;
    }


    /**
     * Sgit_Controller_Action::_auth()
     * 
     * @return
     */
    protected function _auth()
    {

        if ($this->_checkSession)
        {
            $this->_auth = Zend_Auth::getInstance();
            $this->view->auth = $this->_auth->getIdentity();

            $this->_sgit_session = Zend_Registry::get('sgit_session');


            $uri = $this->request->getRequestUri();

            if (!$this->_auth->hasIdentity())
            {
                // Si el Usuario no esta identificado y no se dirige a la página de Login
                if ($this->_controllerName != 'login')
                {
                    // redireccionamos a login
                    $destino = base64_encode(urlencode($uri));
                    $this->_helper->redirector->gotoSimple('index', 'login', null, array('destino' => $destino));
                }
            }
        }
    }


    /**
     * Sgit_Controller_Action::_zona()
     * 
     * @return
     */
    protected function _zona()
    {
        //si se precisa zona
        if ($this->_checkZona)
        {

            $this->_idZona = $this->request->getParam('idZona');

            if ($this->_idZona)
            {
                $this->_loadModel('Datacenter');
                
                $this->view->idZona = $this->_idZona;
                $this->zona = $this->_model->Datacenter->cacheAssoc($this->_idZona, 'nombre');
                $this->view->zona = $this->view->escape($this->zona);

                $datacenter = new Sgit_Form_Element_Select_Datacenter('idZona', array('NotFirstBlank' => true));
                $datacenter->setLabel('');
                $datacenter->setAttrib('onchange', "irazona({$this->_idZona},this.value)");
                $datacenter->setValue($this->_idZona);
                //$options = $this->_model->Datacenter->getAssoc('id','nombre',array('dc = ?'=>1));
                //$datacenter->setMultiOptions($options);

                $datacenter->setDecorators(array('ViewHelper', array(array('data' => 'HtmlTag'), array('tag' => 'span', 'class' => 'changedc')), ));


                $this->view->formchangeDC = $datacenter;


                if (!$this->zona)
                {
                    throw new Zend_Controller_Exception(sprintf('The required Datacenter do not exits for %s', $this->_controllerName . ':' . $this->_actionName));
                }

            } else
            {
                throw new Zend_Controller_Exception(sprintf('Datacenter is required for %s', $this->_controllerName . ':' . $this->_actionName));
            }
        }
    }


    /**
     * Sgit_Controller_Action::_borrar()
     * 
     * @return
     */
    protected function _borrar()
    {
        if (!$this->_id)
            $this->_id = $this->request->getParam('id');

        $n = $this->_model->default->deleteRow($this->_id);
        $this->_afterBorrar();
        $this->_afterExecute();

        $json['status'] = is_numeric($n) ? 'ok' : 'ko';

        $this->postDispatch(); //para que se registre en el profiler sino json corta y no llega a postDipatch
        $this->_helper->json($json);
    }


    /**
     * Sgit_Controller_Action::_editar()
     * 
     * @return
     */
    protected function _editar($reload = false, $tplform = "form")
    {

        if ($this->_main_form)
        {
            $form = 'Application_Form_' . $this->_main_form;
            $this->_form->default = new $form();
        }


        if (!$this->_id)
            $this->_id = $this->request->getParam('id');



        if (!$this->request->isXmlHttpRequest() && $this->request->isGet())
        {
            throw new Zend_Controller_Exception($this->_controllerName . ':' . $this->_actionName . ":{$this->_id} > Solo se puede acceder via ajax");
        }



        $this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);


        $this->view->form = $this->_form->default;
        $this->view->id = $this->_id;

        if ($this->request->isPost())
        {

            if (!$this->_form->default->isValid($this->request->getPost()))
            {
                echo $this->render($tplform);

            } else
            {
                //editar
                //update campos
                $this->_executeEditar();
                $this->_afterEdit();
                $this->_afterAddEdit();
                $this->_afterExecute();
                if ($reload)
                {
                    $json['status'] = 'reload';
                } else
                {
                    $row = $this->_getFila($this->_id);
                    $json['status'] = 'ok';
                    $json['fila'] = $this->view->partial($this->_controllerName . '/fila.phtml', $row);
                }

                $this->postDispatch(); //para que se registre en el profiler sino json corta y no llega a postDipatch
                $this->_helper->json($json);

            }
        } else
        {

            $row = $this->_model->default->getRow($this->_id);
            $row = $this->_prepareValuesToForm($row);
            $this->_form->default->populate($row);

            echo $this->render($tplform);

        }
    }


    /**
     * Sgit_Controller_Action::_insertar()
     * 
     * @return
     */
    protected function _insertar($tplform = "form")
    {

        if ($this->_main_form)
        {
            $form = 'Application_Form_' . $this->_main_form;
            $this->_form->default = new $form();
        }


        if (!$this->request->isXmlHttpRequest())
        {
            throw new Zend_Controller_Exception($this->_controllerName . ':' . $this->_actionName . ' Solo se puede acceder via ajax');

        }

        $this->_helper->layout->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);


        $this->view->form = $this->_form->default;

        //La primera peticion se hace via get, la segunda cuando se procesan los datos via post
        if ($this->request->isPost())
        {
            if (!$this->_form->default->isValid($this->request->getPost()))
            {
                echo $this->render($tplform);
            } else
            {
                //insertar

                //añadir campos
                $id = $this->_executeInsertar();

                $this->_afterAdd();
                $this->_afterAddEdit();
                $this->_afterExecute();
                $row = $this->_getFila($id);


                $json['status'] = 'ok';
                $json['fila'] = $this->view->partial($this->_controllerName . '/fila.phtml', $row);

                $this->postDispatch(); //para que se registre en el profiler sino json corta y no llega a postDipatch
                $this->_helper->json($json);


            }
        } else
        {
            $row = $this->_prepareValuesToForm((array )$row);
            $this->_form->default->populate($row);
            echo $this->render($tplform);
        }

    }


    /**
     * Sgit_Controller_Action::_autocomplete()
     * 
     * @return
     */
    protected function _autocomplete($model = null, $col = null)
    {
        //$this->_helper->layout->disableLayout();
        //$this->_helper->viewRenderer->setNoRender(true);

        $term = $this->request->getParam('term');
        $col = is_null($col) ? $this->request->getParam('col') : $col;
        $idZona = $this->request->getParam('idZona', null);
        $where = ($idZona) ? array('id_zona = ?' => $idZona) : null;


        if (is_null($model))
        {
            $cols = $this->_model->default->autocomplete($term, $col, $where);
        } else
        {
            $cols = $model->autocomplete($term, $col, $where);
        }

        $this->postDispatch(); //para que se registre en el profiler sino json corta y no llega a postDipatch

        $this->_helper->json($cols);

    }


    protected function _getJson()
    {
        $id = $this->request->getParam('id');
        $col = $this->request->getParam('col');


        $row = $this->_model->default->getRow($id);

        $this->postDispatch(); //para que se registre en el profiler sino json corta y no llega a postDipatch
        if ($col)
            $this->_helper->json(array($col => $row[$col]));
        else
            $this->_helper->json($row);

    }


    protected function _afterAdd()
    {
    }
    protected function _afterEdit()
    {
    }
    protected function _afterBorrar()
    {
    }
    protected function _afterAddEdit()
    {
    }
    protected function _afterExecute()
    {
    }


    /**
     * Sgit_Controller_Action::execute()
     * 
     * @return
     */
    protected function _executeEditar()
    {
        if (!$this->_id)
            throw new Zend_Controller_Exception("Es necesario el identificador de fila en el metodo executeEditar");

        $data = $this->_prepareValuesToDb();
        $this->_model->default->updateRow($data, $this->_id);
        return $this->_id;
    }

    protected function _executeInsertar()
    {
        $data = $this->_prepareValuesToDb();


        $this->_id = $this->_model->default->insertRow($data);

        if (!$this->_id)
            throw new Zend_Controller_Exception("Es necesario que se devuelva identificador de fila en el metodo executeInserar");

        return $this->_id;
    }


    /**
     * Sgit_Controller_Action::prepareRowsToTr()
     * 
     * @return
     */
    protected function _prepareRowsToTr($rows, $aColumns = array())
    {


        foreach ((array)$rows as $row)
        {
            $row = $this->_prepareValuesToTr($row);
            //para tenerlo disponible en el partialLoop
           

            if ($this->_idZona)
                $row['idZona'] = $this->_idZona;
            $newrows[] = $row;


        }

        return $newrows;

    }


    /**
     * Sgit_Controller_Action::prepareValuesToForm()
     * 
     * @return
     */
    protected function _prepareValuesToForm($row)
    {
        return $row;
    }

    /**
     * Sgit_Controller_Action::prepareValuesToTr()
     * 
     * @return
     */
    protected function _prepareValuesToTr($row)
    {
        return $row;
    }

    /**
     * Sgit_Controller_Action::prepareValuesToDb()
     * 
     * @return
     */
    protected function _prepareValuesToDb()
    {
        return $this->_form->default->getValues();
    }
    /**
     * Sgit_Controller_Action::getFila()
     * 
     * @return
     */
    protected function _getFila($id)
    {

        $row = $this->_model->default->getRow($id);

        $row = $this->_prepareValuesToTr($row);
        return $row;
    }

    /**
     * Sgit_Controller_Action::getValueFromFormElement()
     * 
     * @return
     */
    protected function _getValueFromFormElement($element, $key)
    {
        if ($key)
        {
            $select = $this->_model->default->$element();
            return $select->getMultiOption($key);
        } else
        {
            return '';
        }

    }


    protected function _acl()
    {

        if ($this->_checkSession)
        {

            if (in_array($this->_actionName, array('denied', 'register')))
                return true;

            $this->_acl = $this->_getAcl();

            if (is_numeric($this->_idZona))
                $codZona = ':' . $this->_idZona;
            else
                $codZona = '';


            $key_resource = strtolower($this->_controllerName . ':' . $this->_actionName . $codZona);
            $key_parent = strtolower($this->_controllerName . $codZona);


            $id_usuario = $this->_auth->getIdentity()->id;

            //permite acceso en funcion de Sgit_Acl_Assert_Check
            $this->_acl->allow(null, null, null, new Sgit_Acl_Assert_Check($this->_checkAcceso));


            if (!$this->_acl->has($key_resource))
            {
                print ' No existe recurso ' . $key_resource;
                return true;
            }

            if (!$this->_acl->isAllowed($id_usuario, $key_resource))
            {

                if ($this->request->isXmlHttpRequest())
                {
                    $this->_helper->layout->disableLayout();
                }


                $this->request->setControllerName('error');
                $this->request->setActionName('denied');


            }

            return true;
        }

    }


    /**
     * Sgit_Controller_Action::_getCache()
     * 
     * @return
     */
    protected function _getCache()
    {
        if (null === $this->_cache)
        {
            $this->_cache = $this->getInvokeArg('bootstrap')->getResource('Cache');
        }
        return $this->_cache;
    }


    protected function _getAcl()
    {
        $this->_cache = $this->_getCache();

        if (!$acl = $this->_cache->load('acl'))
        {
            $acl = new Sgit_Acl();
            $this->_cache->save($acl, 'acl');
        }

        return $acl;
    }

    protected function _setAcl($acl)
    {
        $this->_cache = $this->_getCache();
        $this->_cache->remove('acl');
        $this->_cache->save($acl, 'acl');
        return $acl;
    }

    protected function _updateAcl()
    {
        $this->_cache = $this->_getCache();
        $this->_cache->remove('acl');
        $acl = new Sgit_Acl();
        $this->_cache->save($acl, 'acl');
        return $acl;
    }


    protected function _getFiltrosValues($filtros)
    {
        
        
        
        $values = array();
        if ($this->request->isPost())
        {
            if ($filtros->isValid($this->request->getPost()))
            {
                $values = $filtros->getValues();
            }
        }else{
            $values=$this->request->getParams();
        }
        return $values;
    }

    protected function _loadModel($model)
    {
        $modelo = 'Application_Model_' . $model;
        if (!$this->_model->$model instanceof $modelo)
        {
            $this->_model->$model = new $modelo();
        }
    }

    function postDispatch()
    {

        $this->_logger = Zend_Registry::get('loggerTxt');

        try
        {
            if ($this->_profiler == true)
            {
                $db = Zend_Registry::get("database");

                $profiler = $db->getProfiler();

                $i = 0;

                if ($profiler->getTotalNumQueries())
                {
                    foreach ($profiler->getQueryProfiles() as $query)
                    {
                        if ($query->getQueryType() == 1)
                            continue;

                        $data[$i]['sql'] = $query->getQuery();
                        $data[$i]['time'] = round($query->getElapsedSecs(), 5);
                        $data[$i]['params'] = implode(' || ', $query->getQueryParams());
                        $data[$i]['session'] = session_id();
                        $data[$i]['fecha'] = date('Y-m-d H:i:s');
                        $data[$i]['model'] = $this->_controllerName . ':' . $this->_actionName;


                        $format = str_pad($data[$i]['time'], 8) . str_pad($data[$i]['model'], 38) . str_replace("\n", ' ', $data[$i]['sql']);
                        $this->_logger->info($format);
                        $i++;
                    }
                }
                $db->getProfiler()->setEnabled(false);

                $model = new Application_Model_Profiles();
                foreach ((array )$data as $data)
                {
                    $model->insert($data);
                }

            }
        }
        catch (exception $e)
        {
            echo $e->__toString();
        }


    }


}
